package sqlite

// 导入Go标准库的database/sql包，提供通用SQL数据库接口
import (
	"database/sql"
	"errors"
	"fmt"
	"strconv"
	"student_api/internal/types"

	//_ "github.com/mattn/go-sqlite3"
	_ "modernc.org/sqlite"
	"student_api/internal/config"
)

// Sqlite Sqlite结构体，用于封装SQLite数据库连接
type Sqlite struct {
	// Db字段，指向sql.DB的指针，用于执行数据库操作
	Db *sql.DB
}

func (s *Sqlite) CreateStudent(name string, email string, age int) (int64, error) {
	stmt, err := s.Db.Prepare("INSERT INTO students (name, email, age) VALUES (?, ?, ?)")
	if err != nil {
		return 0, err
	}
	defer stmt.Close()

	result, err := stmt.Exec(name, email, age)
	if err != nil {
		return 0, err
	}

	id, err := result.LastInsertId()
	if err != nil {
		return 0, err
	}

	return id, nil
}

// New 创建并返回一个SQLite数据库连接实例
func New(cfg *config.Config) (*Sqlite, error) {
	// 打开SQLite3数据库连接，使用配置中的存储路径
	db, err := sql.Open("sqlite", cfg.StoragePath)

	// 检查数据库连接是否成功
	if err != nil {
		// 如果连接失败，返回nil和错误信息
		return nil, err
	}

	// 执行SQL语句：在SQLite数据库中创建students表（如果不存在）
	_, err = db.Exec(`CREATE TABLE IF NOT EXISTS students (
		id INTEGER PRIMARY KEY AUTOINCREMENT,  
		name TEXT,                             
		email TEXT,                             
		age INTEGER                           
	);`)
	// 检查建表操作是否成功
	if err != nil {
		// 如果建表失败，返回空值和错误信息
		return nil, err
	}

	// 返回Sqlite实例和nil错误（成功时）
	return &Sqlite{Db: db}, nil
}

// GetStudentById 根据学生ID从SQLite数据库查询学生信息
func (s *Sqlite) GetStudentById(id int64) (types.Student, error) {
	// 准备 SQL 查询语句
	stmt, err := s.Db.Prepare("SELECT id, name, email, age FROM students WHERE id = ? LIMIT 1")
	if err != nil {
		return types.Student{}, err
	}

	// 延迟关闭语句，确保资源释放
	defer stmt.Close()

	// 声明学生结构体变量
	var student types.Student

	// 执行查询并将结果扫描到结构体字段
	// 执行SQL查询并将结果扫描到student结构体
	err = stmt.QueryRow(id).Scan(&student.Id, &student.Name, &student.Email, &student.Age)

	// 检查查询是否出错
	if err != nil {
		// 如果是"查无数据"的错误
		if errors.Is(err, sql.ErrNoRows) {
			// 返回业务友好的错误提示：未找到对应ID的学生
			return types.Student{}, fmt.Errorf("no student found with id %s", fmt.Sprintf(strconv.FormatInt(id, 10)))
		}
		// 其他数据库错误，返回通用查询错误信息
		return types.Student{}, fmt.Errorf("query error: %w", err)
	}

	// 返回查询到的学生信息
	return student, nil
}

func (s *Sqlite) GetStudents() ([]types.Student, error) {
	// 准备SQL查询语句
	stmt, err := s.Db.Prepare("SELECT id, name, email, age FROM students")
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	// 执行查询
	rows, err := stmt.Query()
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	// 遍历结果集并映射到结构体切片
	var students []types.Student
	for rows.Next() {
		var student types.Student
		err := rows.Scan(&student.Id, &student.Name, &student.Email, &student.Age)
		if err != nil {
			return nil, err
		}
		students = append(students, student)
	}

	// 检查遍历过程中是否出错
	if err := rows.Err(); err != nil {
		return nil, err
	}

	return students, nil
}
